﻿using System;
using OverStore.Configuration.Validation;
using OverStore.Exceptions.Configuration;
using OverStore.Runtime.OverStoreContext;
using OverStore.Runtime.ObjectRepository.Depot.IdentifierGenerator;

namespace OverStore.Configuration.ObjectRepository.Depot.IdentifierGenerator
{    
    /// <summary>
    /// Contains configuration parameters for creating instances of 
    /// 
    /// </summary>
    /// <typeparam name="TInstance">The type of the instance.</typeparam>
    public sealed class SequentialGeneratorConfiguration<TInstance> : IComponentConfiguration<IIdentifierGenerator<TInstance, int>>,
        ISupportValidation
        where TInstance : class
    {
        /// <summary>
        /// Initializes a new instance of the <see cref="SequentialGeneratorConfiguration{TInstance}"/> class.
        /// </summary>
        public SequentialGeneratorConfiguration()
        {
            Increment = 1;
        }

        /// <summary>
        /// Gets or sets the starting result for generation.
        /// </summary>
        public int StartingValue { get; set; }

        /// <summary>
        /// Gets or sets the result added to last identifier for obtain next identifier.
        /// </summary>
        public int Increment { get; set; }

        /// <summary>
        /// Creates the new instance of <see cref="IIdentifierGenerator{TInstance, TIdentifier}"/> with specified configuration.
        /// </summary>
        /// <param name="context">The context provides set of services may be useful for new instance of identifier generator.</param>
        /// <returns>
        /// The new instance of <see cref="IIdentifierGenerator{TInstance, TIdentifier}"/>.
        /// </returns>
        public IIdentifierGenerator<TInstance, int> CreateComponent(IOverStoreContext context)
        {
            if (context == null)
                throw new ArgumentNullException("context");
            if (Increment == 0)
                throw this.ConfigurationException("Increment should be different than zero.");
            return new SequentialGenerator<TInstance, int>(StartingValue, Increment);
        }

        /// <summary>
        /// Perform component validation. Method should validate only
        /// component configuration itself, not sub components.
        /// If configuration is valid, null result should returns.
        /// </summary>
        /// <returns>
        ///     <see cref="T:OverStore.Configuration.ValidationResults"/> describes errors found in component configuration.
        /// </returns>
        public ValidationResult Validate()
        {
            return new ValidationResult(this)
                .AddError(Increment == 0, "Increment value should be different than zero.");
        }
    }
}
